package lightswitch.server.code.sqlhelper.expression;

import java.util.ArrayList;

import lightswitch.server.code.object.DataRow;
import lightswitch.server.code.object.Database;
import lightswitch.server.code.object.MyEntry;
import lightswitch.server.code.object.Property;
import lightswitch.server.code.object.Reference;
import lightswitch.server.code.object.Table;
import lightswitch.server.code.util.OrderType;
import lightswitch.server.code.util.StringHelper;

public class NormalTable extends AbstractTable {
	public NormalTable() {
		
		propertyList  = new ArrayList<Property>();
		dataRowList = new ArrayList<>();
		referencesList = new ArrayList<>();

	}

	public NormalTable(String statement) {
		propertyList  = new ArrayList<Property>();
		dataRowList = new ArrayList<>();
		referencesList = new ArrayList<>();
		
		statement = StringHelper.NormalizeString(statement);
		String[] strList = statement.split(" ");
		if (strList.length == 1) {
			name = strList[0];
			alias = name;
		} else {
			if (strList.length == 3 && strList[1].equals("as")) {
				name = strList[0];
				alias = strList[2];
			} else {
				if (strList.length == 2) {
					name = strList[0];
					alias = strList[1];
				} else {
					// int k;
					// throw exception
					return;
				}
			}
		}
	}

	public String toString() {
		String t = "(";
		t = t + this.name + " as " + this.alias;
		return t + ")";
	}
	

	public void InitTable() {
		// lấy dữ liệu từ bảng ở đây. có tên bảng rồi.
		Table tb = Database.getLoadedTable(name);
		this.propertyList = Table.convertProperties(tb.getListOfProperties(),
				this.alias);
		this.referencesList = tb.getListOfReferences();
		this.dataRowList = Table.convertDataRows(tb.getListOfDataRows(),
				this.alias);
	}

	public boolean checkRef(Reference ref, int index1, NormalTable tb2,
			int index2) {
		DataRow _row1 = dataRowList.get(index1);
		DataRow _row2 = tb2.dataRowList.get(index2);
		if (!tb2.name.equals(ref.getTableRef())) {
			return true;// ref ko lien quan

		}
		MyEntry entry1 = _row1.getValue(this.alias, ref.getField());
		MyEntry entry2 = _row2.getValue(tb2.alias, ref.getFieldRef());
		if (entry1 == null || entry2 == null)
			return true; // ref ko lien quan
		if (entry1.getValue().equals(entry2.getValue()))
			return true;

		return false;
	}

	public boolean checkAllRefs(int index1, NormalTable tb2, int index2) {
		for (int k = 0; k < referencesList.size(); k++) {
			if (!checkRef(referencesList.get(k), index1, tb2, index2)) {
			
				return false;
			}
		}
		return true;
	}

	public NormalTable MultiWith(NormalTable _tb, Expression ex) {
		NormalTable _result = new NormalTable();

		for(int i=0;i<propertyList.size();i++)
		{
			_result.propertyList.add(new Property(propertyList.get(i)));
		}
		for(int i=0;i<_tb.propertyList.size();i++)
		{
			_result.propertyList.add(new Property(_tb.propertyList.get(i)));
		}
		

		for (int i = 0; i < dataRowList.size(); i++) {
			for (int j = 0; j < _tb.dataRowList.size(); j++) {
			 {
				 DataRow _row = new DataRow(dataRowList.get(i));
				 _row.PlusDataRow(_tb.dataRowList.get(j));
				 //XXX
				 if((boolean)ex.GetValue(_row,null))
				 {
					 _result.dataRowList.add(_row);
				 }
				}
			}
		}
		_result.referencesList.addAll(referencesList);
		_result.referencesList.addAll(_tb.referencesList);

		return _result;
	}

	public void RemoveColumn(int index) {
		propertyList.remove(index);
		for (int i = 0; i < dataRowList.size(); i++) {
			dataRowList.get(i).removeField(index);
		}
	}

	public void WrapRows(int index1, int index2) {
		DataRow row = new DataRow(dataRowList.get(index1));
		dataRowList.set(index1, new DataRow(dataRowList.get(index2)));
		dataRowList.set(index2, row);
	}

	public void SortTable(int index, String type) {
		if (type.equals(OrderType.ASC)) {
			for (int i = 0; i < dataRowList.size(); i++) {
				for (int j = i; j < dataRowList.size(); j++) {
					if (dataRowList
							.get(i)
							.getEntry(index)
							.getValue()
							.compareTo(
									dataRowList.get(j).getEntry(index)
											.getValue()) > 0) {
						// hoán vị 2 dòng:
						WrapRows(i, j);

					}
				}
			}
		} else {
			if (type.equals(OrderType.DESC)) {
				for (int i = 0; i < dataRowList.size(); i++) {
					for (int j = i; j < dataRowList.size(); j++) {
						if (dataRowList
								.get(i)
								.getEntry(index)
								.getValue()
								.compareTo(
										dataRowList.get(j).getEntry(index)
												.getValue()) < 0) {
							// hoán vị 2 dòng:
							WrapRows(i, j);

						}
					}
				}
			}
		}
	}
	public int getIndexOfColumn(String propertyName)
	{
		for(int i=0;i<propertyList.size();i++)
		{
			if(propertyList.get(i).getName().equals(propertyName))
			{
				return i;
			}
		}
		return -1;
	}
}
